﻿@using System
@using System.Globalization
@using System.Linq
@using System.Net
@using System.Reflection
@using Microsoft.AspNetCore.Diagnostics.RazorViews
@using Microsoft.AspNetCore.Diagnostics
@functions
{
    public ErrorPage(ErrorPageModel model)
    {
        Model = model;
    }

    public ErrorPageModel Model { get; set; }
}
@{
    // TODO: Response.ReasonPhrase = "Internal Server Error";
    Response.ContentType = "text/html; charset=utf-8";
    string? location = string.Empty;
}
<!DOCTYPE html>
<html lang="@CultureInfo.CurrentUICulture.TwoLetterISOLanguageName" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>@Model.Title</title>
    <style>
        <%$ include: ErrorPage.css %>
    </style>
</head>
<body>
    <h1>@Resources.ErrorPageHtml_UnhandledException</h1>
    @foreach (var errorDetail in Model.ErrorDetails)
    {
        <div class="titleerror">
            @errorDetail.Error!.GetType().Name: @{
                Output.Write(HtmlEncodeAndReplaceLineBreaks(errorDetail.Error.Message));
            }
        </div>

        var firstFrame = errorDetail.StackFrames.FirstOrDefault();
        if (firstFrame != null)
        {
            location = firstFrame.Function;
        }
        if (!string.IsNullOrEmpty(location) && firstFrame != null && !string.IsNullOrEmpty(firstFrame.File))
        {
            <p class="location">@location in <code title="@firstFrame.File">@System.IO.Path.GetFileName(firstFrame.File)</code>, line @firstFrame.Line</p>
        }
        else if (!string.IsNullOrEmpty(location))
        {
            <p class="location">@location</p>
        }
        else
        {
            <p class="location">@Resources.ErrorPageHtml_UnknownLocation</p>
        }

        var reflectionTypeLoadException = errorDetail.Error as ReflectionTypeLoadException;
        if (reflectionTypeLoadException != null)
        {
            if (reflectionTypeLoadException.LoaderExceptions.Length > 0)
            {
                <h3>Loader Exceptions:</h3>
                <ul>
                    @foreach (var ex in reflectionTypeLoadException.LoaderExceptions)
                    {
                        <li>@ex!.Message</li>
                    }
                </ul>
            }
        }
    }
    <ul id="header">
        <li id="stack" tabindex="1" class="selected">
            @Resources.ErrorPageHtml_StackButton
        </li>
        <li id="query" tabindex="2">
            @Resources.ErrorPageHtml_QueryButton
        </li>
        <li id="cookies" tabindex="3">
            @Resources.ErrorPageHtml_CookiesButton
        </li>
        <li id="headers" tabindex="4">
            @Resources.ErrorPageHtml_HeadersButton
        </li>
        <li id="routing" tabindex="5">
            @Resources.ErrorPageHtml_RoutingButton
        </li>
    </ul>

    <div id="stackpage" class="page">
        <ul>
            @{
                var exceptionCount = 0;
                var stackFrameCount = 0;
                var exceptionDetailId = "";
                var frameId = "";
            }
            @foreach (var errorDetail in Model.ErrorDetails)
            {
                exceptionCount++;
                exceptionDetailId = "exceptionDetail" + exceptionCount;

                <li>
                    <h2>@errorDetail.Error!.GetType().Name: @errorDetail.Error.Message</h2>
                    <ul>
                        @foreach (var frame in errorDetail.StackFrames)
                        {
                            stackFrameCount++;
                            frameId = "frame" + stackFrameCount;

                            <li class="frame" id="@frameId">
                                @if (string.IsNullOrEmpty(frame.File))
                                {
                                    <h3>@frame.Function</h3>
                                }
                                else
                                {
                                    <h3>@frame.Function in <code title="@frame.File">@System.IO.Path.GetFileName(frame.File)</code></h3>
                                }

                                @if (frame.Line != 0 && frame.ContextCode.Any())
                                {
                                    <button class="expandCollapseButton" data-frameId="@frameId">+</button>
                                    <div class="source">
                                        @if (frame.PreContextCode.Any())
                                        {
                                            <ol start="@frame.PreContextLine" class="collapsible">
                                                @foreach (var line in frame.PreContextCode)
                                                {
                                                    <li><span>@line</span></li>
                                                }
                                            </ol>
                                        }

                                        <ol start="@frame.Line" class="highlight">
                                            @foreach (var line in frame.ContextCode)
                                            {
                                                <li><span>@line</span></li>
                                            }
                                        </ol>

                                        @if (frame.PostContextCode.Any())
                                        {
                                            <ol start='@(frame.Line + 1)' class="collapsible">
                                                @foreach (var line in frame.PostContextCode)
                                                {
                                                    <li><span>@line</span></li>
                                                }
                                            </ol>
                                        }
                                    </div>
                                }
                            </li>
                        }
                    </ul>
                </li>
                <li>
                    <br />
                    <div class="rawExceptionBlock">
                        <button class="showRawException" data-exceptionDetailId="@exceptionDetailId">Show raw exception details</button>
                        <div id="@exceptionDetailId" class="rawExceptionDetails">
                            <pre class="rawExceptionStackTrace">@errorDetail.Error.ToString()</pre>
                        </div>
                    </div>
                </li>
            }
        </ul>
    </div>

    <div id="querypage" class="page">
        @if (Model.Query.Any())
        {
            <table>
                <thead>
                    <tr>
                        <th>@Resources.ErrorPageHtml_VariableColumn</th>
                        <th>@Resources.ErrorPageHtml_ValueColumn</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var kv in Model.Query.OrderBy(kv => kv.Key))
                    {
                        foreach (var v in kv.Value)
                        {
                            <tr>
                                <td>@kv.Key</td>
                                <td>@v</td>
                            </tr>
                        }
                    }
                </tbody>
            </table>
        }
        else
        {
            <p>@Resources.ErrorPageHtml_NoQueryStringData</p>
        }
    </div>

    <div id="cookiespage" class="page">
        @if (Model.Cookies.Any())
        {
            <table>
                <thead>
                    <tr>
                        <th>@Resources.ErrorPageHtml_VariableColumn</th>
                        <th>@Resources.ErrorPageHtml_ValueColumn</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var kv in Model.Cookies.OrderBy(kv => kv.Key))
                    {
                        <tr>
                            <td>@kv.Key</td>
                            <td>@kv.Value</td>
                        </tr>
                    }
                </tbody>
            </table>
        }
        else
        {
            <p>@Resources.ErrorPageHtml_NoCookieData</p>
        }
    </div>

    <div id="headerspage" class="page">
        @if (Model.Headers.Any())
        {
            <table>
                <thead>
                    <tr>
                        <th>@Resources.ErrorPageHtml_VariableColumn</th>
                        <th>@Resources.ErrorPageHtml_ValueColumn</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var kv in Model.Headers.OrderBy(kv => kv.Key))
                    {
                        foreach (var v in kv.Value)
                        {
                            <tr>
                                <td>@kv.Key</td>
                                <td>@v</td>
                            </tr>
                        }
                    }
                </tbody>
            </table>
        }
        else
        {
            <p>@Resources.ErrorPageHtml_NoHeaderData</p>
        }
    </div>

    <div id="routingpage" class="page">
        <h2>@Resources.ErrorPageHtml_Endpoint</h2>
        @if (Model.Endpoint != null)
        {
            <table>
                <thead>
                    <tr>
                        <th>@Resources.ErrorPageHtml_NameColumn</th>
                        <th>@Resources.ErrorPageHtml_ValueColumn</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>@Resources.ErrorPageHtml_EndpointDisplayName</td>
                        <td>@Model.Endpoint.DisplayName</td>
                    </tr>
                    @if (!string.IsNullOrEmpty(Model.Endpoint.RoutePattern))
                    {
                        <tr>
                            <td>@Resources.ErrorPageHtml_EndpointRoutePattern</td>
                            <td>@Model.Endpoint.RoutePattern</td>
                        </tr>
                    }
                    @if (Model.Endpoint.Order != null)
                    {
                        <tr>
                            <td>@Resources.ErrorPageHtml_EndpointRouteOrder</td>
                            <td>@Model.Endpoint.Order</td>
                        </tr>
                    }
                    @if (!string.IsNullOrEmpty(Model.Endpoint.HttpMethods))
                    {
                        <tr>
                            <td>@Resources.ErrorPageHtml_EndpointRouteHttpMethod</td>
                            <td>@Model.Endpoint.HttpMethods</td>
                        </tr>
                    }
                </tbody>
            </table>
        }
        else
        {
            <p>@Resources.ErrorPageHtml_NoEndpoint</p>
        }
        <h2>@Resources.ErrorPageHtml_Metadata</h2>
        @if (Model.Endpoint?.Metadata?.Count > 0)
        {
            <table>
                <thead>
                    <tr>
                        <th>@Resources.ErrorPageHtml_MetadataTypeColumn</th>
                        <th>@Resources.ErrorPageHtml_MetadataDetail</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var metadata in Model.Endpoint.Metadata)
                    {
                        <tr>
                            <td><span title="@(metadata.GetType().FullName ?? string.Empty)">@metadata.GetType().Name</span></td>
                            <td>
                                @{
                                    Output.Write(HtmlEncodeAndReplaceLineBreaks(metadata.ToString() ?? string.Empty));
                                }
                            </td>
                        </tr>
                    }
                </tbody>
            </table>
        }
        <h2>@Resources.ErrorPageHtml_RouteValues</h2>
        @if (Model.RouteValues != null && Model.RouteValues.Any())
        {
            <table>
                <thead>
                    <tr>
                        <th>@Resources.ErrorPageHtml_VariableColumn</th>
                        <th>@Resources.ErrorPageHtml_ValueColumn</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var kv in Model.RouteValues.OrderBy(kv => kv.Key))
                    {
                        <tr>
                            <td>@kv.Key</td>
                            <td>@(kv.Value!)</td>
                        </tr>
                    }
                </tbody>
            </table>
        }
        else
        {
            <p>@Resources.ErrorPageHtml_NoRouteValues</p>
        }
    </div>

    <script>
        //<!--
        <%$ include: ErrorPage.js %>
        //-->
    </script>
</body>
</html>
